# Replication Code for:
# The Comparative Meaning of Political Space: A Comprehensive Modeling Approach
# Author: Garret Binding / Jelle Koedam / Marco Steenbergen
# Created: 3/1/2023
  
rm(list = ls());gc()

library(brms)
library(cmdstanr)
library(bayesplot)
library(posterior)
library(abind)
library(dplyr)
library(tidyr)
library(ggplot2)
library(forcats)
library(xtable)
library(logr)

options("logr.autolog" = TRUE)
# Open the log
lf <- log_open(file.path("log.log"))
# Send message to log
log_code()

sessionInfo()

# R version 4.2.1 (2022-06-23)
# Platform: x86_64-pc-linux-gnu (64-bit)
# Running under: Ubuntu 20.04.4 LTS
# 
# Matrix products: default
# BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
# LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
# 
# locale:
#   [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
# [6] LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
# [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
# 
# attached base packages:
#   [1] stats     graphics  grDevices utils     datasets  methods   base     
# 
# other attached packages:
#   [1] logr_1.3.3      xtable_1.8-4    forcats_0.5.1   ggplot2_3.3.6   tidyr_1.2.0     dplyr_1.0.9     abind_1.4-5     posterior_1.2.2 bayesplot_1.9.0
# [10] cmdstanr_0.5.2  brms_2.17.0     Rcpp_1.0.8.3   
# 
# loaded via a namespace (and not attached):
#   [1] nlme_3.1-157           matrixStats_0.62.0     xts_0.12.1             threejs_0.3.3          rstan_2.21.5           tensorA_0.36.2        
# [7] tools_4.2.1            backports_1.4.1        utf8_1.2.2             R6_2.5.1               DT_0.23                DBI_1.1.3             
# [13] colorspace_2.0-3       withr_2.5.0            tidyselect_1.2.0       gridExtra_2.3          prettyunits_1.1.1      processx_3.6.1        
# [19] Brobdingnag_1.2-7      compiler_4.2.1         cli_3.4.1              shinyjs_2.1.0          colourpicker_1.1.1     scales_1.2.0          
# [25] dygraphs_1.1.1.6       checkmate_2.1.0        mvtnorm_1.1-3          ggridges_0.5.3         callr_3.7.0            stringr_1.4.0         
# [31] digest_0.6.29          StanHeaders_2.21.0-7   base64enc_0.1-3        pkgconfig_2.0.3        htmltools_0.5.2        fastmap_1.1.0         
# [37] htmlwidgets_1.5.4      rlang_1.0.6            rstudioapi_0.13        shiny_1.7.1            farver_2.1.0           generics_0.1.2        
# [43] zoo_1.8-10             jsonlite_1.8.0         crosstalk_1.2.0        gtools_3.9.2.2         distributional_0.3.0   inline_0.3.19         
# [49] magrittr_2.0.3         loo_2.5.1              Matrix_1.4-1           munsell_0.5.0          fansi_1.0.3            lifecycle_1.0.3       
# [55] stringi_1.7.6          pkgbuild_1.3.1         plyr_1.8.7             grid_4.2.1             parallel_4.2.1         promises_1.2.0.1      
# [61] crayon_1.5.1           miniUI_0.1.1.1         lattice_0.20-45        knitr_1.39             ps_1.7.1               pillar_1.7.0          
# [67] igraph_1.3.2           markdown_1.1           shinystan_2.6.0        reshape2_1.4.4         codetools_0.2-18       stats4_4.2.1          
# [73] rstantools_2.2.0       glue_1.6.2             data.table_1.14.2      RcppParallel_5.1.5     vctrs_0.5.1            httpuv_1.6.5          
# [79] gtable_0.3.0           purrr_0.3.4            assertthat_0.2.1       xfun_0.31              mime_0.12              this.path.helper_0.1.0
# [85] coda_0.19-4            later_1.3.0            this.path_1.2.0        tibble_3.1.7           shinythemes_1.2.0      ellipsis_0.3.2        
# [91] bridgesampling_1.1-2

options(mc.cores = parallel::detectCores())

set.seed(2022)

# load data ####
df_id <- read.csv("data/CHES2019V3.csv") %>% 
  dplyr::select(country, eastwest, party_id) %>% 
  distinct()

df_pid <- read.csv("data/1999-2019_CHES_dataset_means(v1).csv")[,1:14] %>% 
  filter(year == 2019)

df <- read.csv("data/CHES2019_experts.csv") %>% 
  merge(df_id, by = "party_id") %>% 
  filter({eastwest == 1 & !(country %in% c("cyp", "lux"))} | {is.na(eastwest) & !(country %in% c("tur", "swi", "nor", "ice"))}) %>% 
  dplyr::select(country:eastwest, 
                party_id:party_name,
                immigrate_policy, multiculturalism, redistribution, environment, spendvtax, deregulation, econ_interven, civlib_laworder, sociallifestyle, religious_principles,
                ethnic_minorities, nationalism, urban_rural, protectionism, regions, # people_vs_elite, 
                eu_position = position, eu_cohesion, eu_foreign, eu_intmark, eu_budgets, eu_asylum, lrgen, lrecon, galtan) %>% 
  mutate(expert = paste0(country, ".", id))

df$lrgen[df$lrgen == -1] <- NA
df$lrecon[df$lrecon == -1] <- NA
df$galtan[df$galtan == -1] <- NA
df$lrecon[df$lrecon %in% c("", ".d")] <- NA
df$galtan[df$galtan %in% c("", ".d")] <- NA
df$lrecon <- as.numeric(df$lrecon)
df$galtan <- as.numeric(df$galtan)

df[,7:21] <- df[,7:21] + 1

p_id <- 1:length(unique(df$party_id)) # parties
c_id <- 1:length(unique(df$country)) # countries
e_id <- 1:length(unique(df$expert)) # experts
i_id <- 1:21 # issues

names(p_id) <- as.character(unique(df$party_id))
names(c_id) <- unique(df$country)
names(e_id) <- unique(df$expert)
names(i_id) <- colnames(df[,7:27])

df$p_id <- p_id[as.character(df$party_id)]
df$c_id <- c_id[df$country]
df$e_id <- e_id[df$expert]

# starting values (to address rotational invariance)
p_start <- df %>% 
  select(p_id, lrgen, lrecon, galtan) %>% 
  group_by(p_id) %>% 
  summarize(lr = median(lrgen, na.rm = T),
            lrecon = median(lrecon, na.rm = T),
            galtan = median(galtan, na.rm = T)) %>% 
  ungroup()
p_start[,2:4] <- apply(p_start[,2:4], 2, function(x) (x - mean(x)) / sd(x))
p_start <- p_start %>% 
  arrange(p_id)

df_long <- df[, c(7:27, 32:34)] %>% 
  pivot_longer(cols = 1:21)
df_long$i_id <- i_id[df_long$name]
df_long <- na.omit(df_long)

# run models ####
dir.create("out")
source("01_run_models.R")

# extract main qoi ####
source("02_write_out.R")

# generate figures and tables ####
dir.create("figures")
dir.create("tables")
source("03_main.R")

log_close()